package com.csi.bumblebee.service.impl;

import com.csi.bumblebee.domain.dictionary.ExamValuation;
import com.csi.bumblebee.domain.dictionary.JobExam;
import com.csi.bumblebee.domain.user.ExamResult;
import com.csi.bumblebee.domain.user.Resume;
import com.csi.bumblebee.domain.user.Student;
import com.csi.bumblebee.mapper.ExamResultMapper;
import com.csi.bumblebee.mapper.ExamValuationMapper;
import com.csi.bumblebee.mapper.ResumeMapper;
import com.csi.bumblebee.service.ExamResultService;
import com.csi.bumblebee.util.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author HUOJT
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ExamResultServiceImpl implements ExamResultService {

    @Autowired
    @Qualifier("jdkRedisTemplate")
    private RedisTemplate<String, Serializable> redisTemplate;

    @Autowired
    private ExamResultMapper examResultMapper;

    @Autowired
    private ExamValuationMapper examValuationMapper;

    @Autowired
    private ResumeMapper resumeMapper;

    @Override
    public String makeScore(ExamResult examResult) {

        // 结果参数
        int skillACorrectCount = 0;
        int skillACorrectScore = 0;
        int skillACount = 0;
        int skillAScore = 0;
        int skillBCorrectCount = 0;
        int skillBCorrectScore = 0;
        int skillBCount = 0;
        int skillBScore = 0;
        int skillCCorrectCount = 0;
        int skillCCorrectScore = 0;
        int skillCCount = 0;
        int skillCScore = 0;
        int skillCorrectCount = 0;
        int skillCorrectScore = 0;
        int skillCount = 0;
        int skillScore = 0;
        String result = null;

        // 判断试卷是否可用
        if (examResult != null && examResult.getJobType() != null && examResult.getJobType().getJobExamList() != null) {

            // 判卷
            for (JobExam jobExam : examResult.getJobType().getJobExamList()) {
                // 题目存在
                if (jobExam != null) {

                    // A类型
                    if ("SY2022102210352066666".equals(jobExam.getSkillTypeId())) {

                        skillAScore += jobExam.getScore();
                        skillACount++;

                        // 答题正确
                        if (jobExam.getAnswer() != null && jobExam.getAnswer().equals(jobExam.getStudentAnswer())) {
                            jobExam.setCorrect(true);
                            jobExam.setStudentScore(jobExam.getScore());
                            skillACorrectCount++;
                            skillACorrectScore += jobExam.getScore();
                        }
                    }

                    // B类型
                    else if ("SY2022102210352166666".equals(jobExam.getSkillTypeId())) {

                        skillBScore += jobExam.getScore();
                        skillBCount++;

                        // 答题正确
                        if (jobExam.getAnswer() != null && jobExam.getAnswer().equals(jobExam.getStudentAnswer())) {
                            jobExam.setCorrect(true);
                            jobExam.setStudentScore(jobExam.getScore());
                            skillBCorrectCount++;
                            skillBCorrectScore += jobExam.getScore();
                        }
                    }

                    // C类型
                    else if ("SY2022102210352266666".equals(jobExam.getSkillTypeId())) {
                        skillCScore += jobExam.getScore();
                        skillCCount++;

                        // 答题正确
                        if (jobExam.getAnswer() != null && jobExam.getAnswer().equals(jobExam.getStudentAnswer())) {
                            jobExam.setCorrect(true);
                            jobExam.setStudentScore(jobExam.getScore());
                            skillCCorrectCount++;
                            skillCCorrectScore += jobExam.getScore();
                        }

                    }

                }

                skillCorrectCount = skillACorrectCount + skillBCorrectCount + skillCCorrectCount;
                skillCount = skillACount + skillBCount + skillCCount;
                skillCorrectScore = skillACorrectScore + skillBCorrectScore + skillCCorrectScore;
                skillScore = skillAScore + skillBScore + skillCScore;

                // 得到分析结果
                if (skillCount > 0) {

                    // 正确率
                    examResult.setSkillCorrectRatio((double) skillCorrectCount / skillCount);
                    if (skillACount > 0) {
                        examResult.setSkillACorrectRatio((double) skillACorrectCount / skillACount);
                    }
                    if (skillBCount > 0) {
                        examResult.setSkillBCorrectRatio((double) skillBCorrectCount / skillBCount);
                    }
                    if (skillCCount > 0) {
                        examResult.setSkillCCorrectRatio((double) skillCCorrectCount / skillCCount);
                    }

                    // 得分率
                    if (skillScore > 0) {
                        examResult.setSkillCorrectScoreRatio((double) skillCorrectScore / skillScore);

                        if (skillAScore > 0) {
                            examResult.setSkillACorrectScoreRatio((double) skillACorrectScore / skillAScore);
                        }
                        if (skillBScore > 0) {
                            examResult.setSkillBCorrectScoreRatio((double) skillBCorrectScore / skillBScore);
                        }
                        if (skillCScore > 0) {
                            examResult.setSkillCCorrectScoreRatio((double) skillCorrectScore / skillCScore);
                        }
                    }

                }
            }

            // id
            examResult.setId(IdUtil.getString(ExamResult.PRE_NAME));

            // 成功录入
            if (examResultMapper.insertExamResult(examResult) == 1) {

                // redis
                redisPut(examResult);

                // 同步到简历表
                String studentId = examResult.getStudentId();
                Resume resume = resumeMapper.findResume(studentId);
                if(resume != null) {
                    resume.setExamResultId(examResult.getId());
                }
                if(resumeMapper.updateResume(resume) == 1) {
                    result = examResult.getId();
                }

            }
        }

        return result;
    }

    /**
     * 得到答题结果
     *
     * @param id id
     * @return 答题结果
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ExamResult getByExamResultId(String id) {

        // 得到评价列表
        List<ExamValuation> examValuationList = examValuationMapper.list();

        // 从redis取
        ExamResult examResult = redisGet(id);

        // mysql
        if (examResult == null) {
            examResult = examResultMapper.getByExamResultId(id);

            //  redis
            if (examResult != null) {
                redisPut(examResult);
            }
        }

        // 给出评价
        if (examResult != null) {
            Double ratio = null;

            // 整体
            if ((ratio = examResult.getSkillCorrectScoreRatio()) != null) {
                for (ExamValuation examValuation : examValuationList) {
                    if (examValuation.getLowestRatio() <= ratio && examValuation.getHighestRatio() > ratio) {
                        examResult.setExamValuation(examValuation);
                        break;
                    }
                }
            }

            // A
            if ((ratio = examResult.getSkillACorrectScoreRatio()) != null) {
                for (ExamValuation examValuation : examValuationList) {
                    if (examValuation.getLowestRatio() <= ratio && examValuation.getHighestRatio() > ratio) {
                        examResult.setExamValuationA(examValuation);
                        break;
                    }
                }
            }

            // B
            if ((ratio = examResult.getSkillBCorrectScoreRatio()) != null) {
                for (ExamValuation examValuation : examValuationList) {
                    if (examValuation.getLowestRatio() <= ratio && examValuation.getHighestRatio() > ratio) {
                        examResult.setExamValuationB(examValuation);
                        break;
                    }
                }
            }

            // C
            if ((ratio = examResult.getSkillCCorrectScoreRatio()) != null) {
                for (ExamValuation examValuation : examValuationList) {
                    if (examValuation.getLowestRatio() <= ratio && examValuation.getHighestRatio() > ratio) {
                        examResult.setExamValuationC(examValuation);
                        break;
                    }
                }
            }
        }

        return examResult;
    }

    /**
     * 放入redis
     *
     * @param examResult 答题结果对象
     */
    private void redisPut(ExamResult examResult) {
        redisTemplate.opsForValue().set(examResult.getId(), examResult, getExpireTime(), TimeUnit.SECONDS);
    }

    /**
     * 从redis取数据
     *
     * @param id 答题结果id
     * @return 答题结果对象
     */
    private ExamResult redisGet(String id) {
        redisTemplate.expire(id, getExpireTime(), TimeUnit.SECONDS);
        return (ExamResult) redisTemplate.opsForValue().get(id);
    }

    /**
     * 从redis取数据
     *
     * @param examResult 答题结果对象
     * @return 答题结果对象
     */
    private ExamResult redisGet(Student examResult) {
        redisTemplate.expire(examResult.getId(), getExpireTime(), TimeUnit.SECONDS);
        return (ExamResult) redisTemplate.opsForValue().get(examResult.getId());
    }

    /**
     * 从redis删除
     *
     * @param id 学生id
     * @return 删除的答题结果
     */
    private ExamResult redisDelete(String id) {
        ExamResult examResult = redisGet(id);
        redisTemplate.delete(id);
        return examResult;
    }

    private long getExpireTime() {
        return 60 * 60 * 24 * 7;
    }
}
